using System;
using System.Collections.Generic;
using BikeSystem.Models;
using Db4objects.Db4o;
using Db4objects.Db4o.Query;
using Db4objects.Db4o.Config;
using System.IO;
namespace BikeSystem.DAL
{
    public class AccountService
    {
        readonly static string YapFileName = Path.Combine(Environment.CurrentDirectory, "bikesystem.yap");


        public void initialize() {

            File.Delete(YapFileName);

            string bikeNo = CommonUtilService.genrateNextSerialNumber("BN");
            using (IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))
            {
                Account account = new Account();
                account.LoginId = "operator";
                account.LoginPwd = "pass";
                account.UserName = "Operator";
                account.Role = ConstData.ACCOUNT_ROLE_OPERATOR;

                db.Store(account);

                Account admaccount = new Account();
                admaccount.LoginId = "admin";
                admaccount.LoginPwd = "pass";
                admaccount.UserName = "Administrator";
                admaccount.Role = ConstData.ACCOUNT_ROLE_ADMIN;

                db.Store(admaccount);


                Bike bike = new Bike();
                bike.BikeNo = bikeNo;
                bike.ModelType = "ROAD_BICYCLE";
                bike.DailyRate = 40;
                bike.HourlyRate = 8;
                bike.Status = true;
                bike.Date = System.DateTime.Now;

                db.Store(bike);

                SystemOption sopt1 = new SystemOption();
                sopt1.OptionCode = CommonUtilService.genrateNextSerialNumber(db, "op");
                sopt1.OptionName = "ROAD_BICYCLE";
                sopt1.OptionType = ConstData.OPTION_BICYCLE_TYPE;
                sopt1.OptionOrder = 0;
                db.Store(sopt1);

                SystemOption sopt2 = new SystemOption();
                sopt2.OptionCode = CommonUtilService.genrateNextSerialNumber(db, "op");
                sopt2.OptionName = "MOUNTAIN_BIKE";
                sopt2.OptionType = ConstData.OPTION_BICYCLE_TYPE;
                sopt2.OptionOrder = 1;
                db.Store(sopt2);

                SystemOption sopt3 = new SystemOption();
                sopt3.OptionCode = CommonUtilService.genrateNextSerialNumber(db, "op");
                sopt3.OptionName = "TANDEM_BICYCLE";
                sopt3.OptionType = ConstData.OPTION_BICYCLE_TYPE;
                sopt3.OptionOrder = 2;
                db.Store(sopt3);


                SystemOption soptr1 = new SystemOption();
                soptr1.OptionCode = CommonUtilService.genrateNextSerialNumber(db, "op");
                soptr1.OptionName = "TANDEM_BICYCLE";
                soptr1.OptionType = ConstData.OPTION_BICYCLE_RATE_HOURLY;
                soptr1.OptionValue = "8";
                soptr1.OptionOrder = 0;
                db.Store(soptr1);

                SystemOption soptr2 = new SystemOption();
                soptr2.OptionCode = CommonUtilService.genrateNextSerialNumber(db, "op");
                soptr2.OptionName = "MOUNTAIN_BIKE";
                soptr2.OptionType = ConstData.OPTION_BICYCLE_RATE_HOURLY;
                soptr2.OptionValue = "10";
                soptr2.OptionOrder = 1;
                db.Store(soptr2);


            };

            RentalService rentalService = new RentalService();

            Rental rental = new Rental();
            rental.BikeNo = bikeNo;
            rental.RentNo = CommonUtilService.genrateNextSerialNumber("rt");
            rental.Contact = "98888765";
            rental.HasLock = false;
            rental.IDType = "NRIC";
            rental.IsReturn = false;
            rental.NRIC = "S89988778";
            rental.OperatorName = "operator";
            rental.RentTime = System.DateTime.Now;

            rentalService.Rental(rental);

            Bill bill = new Bill();
            bill.BillNo = CommonUtilService.genrateNextSerialNumber("bl");
            bill.BillingDate = System.DateTime.Now;
            bill.PaymentMethod = "Bank Card";
            bill.Rate = 8;
            bill.RateType = "HourlyRate";
            bill.RentedTime = 3;
            bill.Amount = 24;

            rental.Bill = bill;
            rentalService.UpdateRental(rental);
        }



        public IList<Account> GetAllAccounts()
        {

            IList<Account> accounts = new List<Account>();
            using (IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))
            {
                IObjectSet result = db.QueryByExample(typeof(Account));
                while (result.HasNext())
                {
                    accounts.Add((Account)result.Next());
                }

                return accounts;
            };

        }

        public Account GetAccountByAccountLoginId(string AccountLoginId)
        {

            using (IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))
            {

                Account account = new Account();
                IQuery query = db.Query();
                query.Constrain(typeof(Account));
                query.Descend("loginId").Constrain(AccountLoginId).Equal();
                IObjectSet result = query.Execute();
                if (result.HasNext())
                {
                    return (Account)result.Next();
                }
                return null;
            };
        }

        public int UpdateAccount(Account account)
        {

            IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
            config.Common.ObjectClass(typeof(Account)).CascadeOnUpdate(true);
            using (IObjectContainer db = Db4oEmbedded.OpenFile(config, YapFileName))
            {

                IQuery query = db.Query();
                query.Constrain(typeof(Account));
                query.Descend("loginId").Constrain(account.LoginId).Equal();
                IObjectSet result = query.Execute();
                if (result.HasNext())
                {

                    Account act = (Account)result.Next();
                    act.LoginPwd = account.LoginPwd;
                    act.Age = account.Age;
                    act.Remark = account.Remark;
                    act.Role = account.Role;
                    act.Sex = account.Sex;
                    act.UserName = account.UserName;
                    act.NRIC = account.NRIC;
                    act.Phone = account.Phone;
                    act.IsNew = false;
                    act.IsUpdated = false;

                    db.Store(act);
                    return 0;
                }
                else {
                    return -1;
                }
            }
        }


        public void InsertAccount(Account account)
        {
            using (IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))
            {

                account.IsNew = false;
                account.IsUpdated = false;

                db.Store(account);
                Console.WriteLine("Stored {0}", account);
            }
        }

        public string DeleteAccount(string AccountLoginId)
        {
            IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
            config.Common.ObjectClass(typeof(Account)).CascadeOnDelete(true);
            using (IObjectContainer db = Db4oEmbedded.OpenFile(config, YapFileName))
            {
                Account account = new Account();
                account.LoginId = AccountLoginId;
                IObjectSet result = db.QueryByExample(account);
                if (result.HasNext())
                {
                    db.Delete(result.Next());
                    return "Delete Success!";
                }
                else
                {
                    return "Delete unsuccess!";
                }

            }

        }

        /**
         * SystemOption services
         * 
         */
        public IList<SystemOption> GetAllOptions()
        {

            IList<SystemOption> systemOptions = new List<SystemOption>();
            using (IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))
            {
                IObjectSet result = db.QueryByExample(typeof(SystemOption));
                while (result.HasNext())
                {
                    systemOptions.Add((SystemOption)result.Next());
                }

                return systemOptions;
            };

        }

        public void InsertSystemOption(SystemOption systemOption)
        {
            using (IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))
            {

                systemOption.IsNew = false;

                db.Store(systemOption);
                Console.WriteLine("Stored {0}", systemOption);
            }
        }

        public string DeleteSystemOption(string optionCode)
        {
            IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
            config.Common.ObjectClass(typeof(SystemOption)).CascadeOnDelete(true);
            using (IObjectContainer db = Db4oEmbedded.OpenFile(config, YapFileName))
            {
                SystemOption systemOption = new SystemOption();
                systemOption.OptionCode = optionCode;
                IObjectSet result = db.QueryByExample(systemOption);
                if (result.HasNext())
                {
                    db.Delete(result.Next());
                    return "Delete Success!";
                }
                else
                {
                    return "Delete unsuccess!";
                }

            }

        }


    }
}
